require'love.thread'
require'love.math'

local cWidth = love.thread.getChannel("jungle_width")
local cHeight = love.thread.getChannel("jungle_height")
local cWallType = love.thread.getChannel("wall_types")
local cFloorType = love.thread.getChannel("floor_types")
local cReps = love.thread.getChannel("reps")
local cReps2 = love.thread.getChannel("reps2")

local jWidth = cWidth:demand()
local jHeight = cHeight:demand()
local jWallTypes = cWallType:demand()
local jFloorTypes = cFloorType:demand()
local reps = cReps:demand()
local reps2 = cReps2:demand()

local jT = {}

function surrounding_walls(x, y, distX, distY)
	local distX = distX or 1
	local distY = distY or 1
	local walls = 0

	if distX == 1 and distY == 1 then
		if jT[jWidth*(y-1)+x] then
			if jT[jWidth*(y-2)+x] then
				if check_wall_types(jT[jWidth*(y-2)+x]) then walls = walls+1 end
			end
			if jT[jWidth*(y-2)+(x-1)] then
				if check_wall_types(jT[jWidth*(y-2)+(x-1)]) then walls = walls+1 end
			end
			if jT[jWidth*(y-2)+(x+1)] then
				if check_wall_types(jT[jWidth*(y-2)+(x+1)]) then walls = walls+1 end
			end
		end
		if jT[jWidth*(y-1)+(x+1)] then
			if check_wall_types(jT[jWidth*(y-1)+(x+1)]) then walls = walls+1 end
		end
		if jT[jWidth*(y-1)+(x-1)] then
			if check_wall_types(jT[jWidth*(y-1)+(x-1)]) then walls = walls+1 end
		end
		if jT[jWidth*(y)+x] then
			if check_wall_types(jT[jWidth*(y)+(x)]) then walls = walls+1 end
			if jT[jWidth*(y)+(x+1)] then
				if check_wall_types(jT[jWidth*(y)+(x+1)]) then walls = walls+1 end
			end
			if jT[jWidth*(y)+(x-1)] then
				if check_wall_types(jT[jWidth*(y)+(x-1)]) then walls = walls+1 end
			end
		end
	else
		for y1 = 1, distY do
			for x1 = 1, distX do
				local tile, tile2
				if jT[jWidth*((y-1)+(y1-1))+(x+x1-1)] then
					if check_wall_types(jT[jWidth*((y-1)+(y1-1))+(x+x1-1)]) then walls = walls+1 end
				end
				if jT[jWidth*((y-1)-y1)+(x-x1)] then
					if check_wall_types(jT[jWidth*((y-1)-y1)+(x-x1)]) then walls = walls+1 end
				end
			end
		end
	end

	return walls
end

function surrounding_diagonals(x, y)
	if check_wall_types(jT[jWidth*(y-1)+x]) then
		local ul, ur, u, bl, br, b, l, r
		if jT[jWidth*(y-2)+(x-1)] then
			ul = jT[jWidth*(y-2)+(x-1)]
		end
		if jT[jWidth*(y-2)+(x+1)] then
			ur = jT[jWidth*(y-1)+(x+1)]
		end
		if jT[jWidth*(y-2)+x] then
			u = jT[jWidth*(y-2)+x]
		end
		if jT[jWidth*(y)+(x-1)] then
			bl = jT[jWidth*(y)+(x-1)]
		end
		if jT[jWidth*(y)+(x+1)] then
			br = jT[jWidth*(y)+(x+1)]
		end
		if jT[jWidth*(y)+x] then
			b = jT[jWidth*(y)+x]
		end
		if jT[jWidth*(y-1)+(x-1)] then
			l = jT[jWidth*(y-1)+(x-1)]
		end
		if jT[jWidth*(y-1)+(x+1)] then
			r = jT[jWidth*(y-1)+(x+1)]
		end

		if check_floor_types(l) and
			check_floor_types(u) and
			check_floor_types(r) then
			jT[jWidth*(y-1)+x] = random_floor_type()
		end		

		if check_floor_types(l) and
			check_floor_types(b) and
			check_floor_types(r) then
			jT[jWidth*(y-1)+x] = random_floor_type()
		end

		-- space tile equivalent goes here
		--[[
		if check_wall_types(ul) and check_wall_types(ur) and
			check_wall_types(bl) and check_wall_types(br) and
			check_wall_types(u) and check_wall_types(b) and
			check_wall_types(l) and check_wall_types(r) then
			--jT[jWidth*(y-1)+x] == 
		end
		]]

	end
end

function check_wall_types(tile)
	for i = 1, #jWallTypes do
		if jWallTypes[i] == tile then
			return true
		end
	end
	return false
end

function check_floor_types(tile)
	for i = 1, #jFloorTypes do
		if jFloorTypes[i] == tile then
			return true
		end
	end
	return false
end

function random_floor_type()
	local r = love.math.random(#jFloorTypes)
	return jFloorTypes[r]
end

function random_wall_type()
	local r = love.math.random(#jWallTypes)
	return jWallTypes[r]
end






print("jungle mapping started")
for y = 1, jHeight do	
	for x = 1, jWidth do
		-- water is less than 33 and greater than 225
		if x < 33 or x > 225 then		
			jT[jWidth*(y-1)+x] = 8
		elseif x == 33 then
			-- water left, land right border
			jT[jWidth*(y-1)+x] = 9
		elseif x == 225 then
			-- water right, land left border
			jT[jWidth*(y-1)+x] = 10
		elseif x == 34 then
			-- water border left, dirt border right
			jT[jWidth*(y-1)+x] = 12
		elseif x == 224 then
			-- water border right, dirt border left
			jT[jWidth*(y-1)+x] = 11
		--else -- handled in main func below
		--	jT[jWidth*(y-1)+x] = love.math.random(5)
		end
	end
end

local minX, maxX = 35, 223

for y = 1, jHeight do
	for x = minX, maxX do
		--jT[jWidth*(y-1)+x] = 1
		local r = love.math.random(100)
		if r < 45 then
			jT[jWidth*(y-1)+x] = random_wall_type()
		else
			jT[jWidth*(y-1)+x] = random_floor_type()
		end

	end
end

for i = 1, reps do
	for y = 1, jHeight do
		for x = minX, maxX do
			local z = surrounding_walls(x, y, 1, 1)
			local q = surrounding_walls(x, y, 2, 2)
			if z > 5 then jT[jWidth*(y-1)+x] = random_wall_type() end
			if q < 2 then jT[jWidth*(y-1)+x] = random_wall_type() end
		end
	end
end

for i = 1, reps2 do 
	for y = 1, jHeight do
		for x = minX, maxX do
			local z = surrounding_walls(x, y, 1, 1)
			if z <= 3 then jT[jWidth*(y-1)+x] = random_floor_type() end

			surrounding_diagonals(x, y)
		end
	end
end


--for i = 1, #jT do
--	print(jT[i])
--end

local jm = love.thread.getChannel("jungle_map")
jm:push(jT)

print("jungle mapping complete")


